/**
  ******************************************************************************
  * @file    algo.c
  * @author
  * @version v0
  * @date    09-07-2019
  *
  * @verbatim
  **/
/* Includes ------------------------------------------------------------------*/


#include "define.h"
#include "disp.h"
#include "power.h"
#include "clk.h"
#include "gpio.h"
#include "time.h"
#include "uart.h"
#include "spk.h"
#include "flash.h"
#include "adc.h"
#include "algo.h"
#include "bp.h"
#include "func.h"
#include "op.h"
#include "pwm.h"


#define  ON    1
uint8 FuzzyF;
uint8  FuzzyMaxTemp;
uint8   FuzzyMaxValue;
uint16  HRPulseCountSUM;
uint8   MAPValue;
uint8   MinInterval;
uint8   NOMORE3;
uint16  AmpValue[5]; 									//修改为Int型. 20110208 因为AmpValue[3]和MaxInterval只有到127,
uint8  PP;
uint8   RefindPulseCount;
uint8   IntervalCount;
uint16  PriMarkCount;
uint8   NOMORE1;
uint8   MaxSlopeValue;
uint8   LowPeakValue;
uint8   HighPeakValue;
uint8   MaxDiffSignal;
uint8   ThresholdValue;
uint8   MeanIndex;
uint16  PriPressureV;
uint16  Countw;
uint16  FilterRam[24];

uint16  PriOscilloSignal;
uint8   DiffSignal;
uint16  UparmScaleValue;
uint8   FuzzyMaxBackup;
uint16  UparmBaseValue;
uint8   PulseCount;
uint8   HRPulseCount;
uint8   PulseRateDIM[33];
uint8   PulseRate;
uint16  MarkCount;
uint16  DetermineValueDia;
uint16  SumInterval;

volatile union byte_bit		AlgoStateFlag;
volatile union byte_bit		AlgorithmFlag;
volatile union word_data		PulsePressure[4];
volatile union byte_bit		MemorySetFlag;

const unsigned char SysTab[]={20,18,17,15,12,17,16,10,11,8,3,13,2,14,16};
const unsigned char DiaTab[]={3,5,8,10,13,17,10,14,3,6,9,12,10,7,4};
const unsigned char AscVal[]={0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
                              0x38,	0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};


void firfilter(void)
{
	unsigned char i;
	if(!RCSensorType) FilterRam[0] =  ZeroCountw - SensorCountw + 0x1000;
	else FilterRam[0] =  SensorCountw - ZeroCountw + 0x1000;
//	if(UparmWWFlag)  OscilloSignalw =480;									//20121002 Uparm filter
	if(InfDefFlag&&!UparmWWFlag)  	OscilloSignalw = 960;					//20190219 if inflate mode and WW mode
	else OscilloSignalw = 480;					//

	OscilloSignalw += FilterRam[7];
	OscilloSignalw += FilterRam[8];
	OscilloSignalw -= FilterRam[0];
	OscilloSignalw -= FilterRam[15];
	OscilloSignalw += FilterRam[6];
	OscilloSignalw += FilterRam[9];
	OscilloSignalw *= 2;
	OscilloSignalw -= FilterRam[2];
	OscilloSignalw -= FilterRam[13];
	OscilloSignalw += FilterRam[5];
	OscilloSignalw += FilterRam[10];
	OscilloSignalw -= FilterRam[1];
	OscilloSignalw -= FilterRam[14];
	OscilloSignalw *= 2;
	OscilloSignalw -= FilterRam[0];
	OscilloSignalw -= FilterRam[15];
	OscilloSignalw += FilterRam[7];
	OscilloSignalw += FilterRam[8];
	OscilloSignalw -= FilterRam[3];
	OscilloSignalw -= FilterRam[12];
	OscilloSignalw -= FilterRam[1];
	OscilloSignalw -= FilterRam[14];

	if(OscilloSignalw > 32768 )
		{
			OscilloSignalw = 0;
		}
	if(InfDefFlag&&!UparmWWFlag)   		//20121002 WW filter
		{
			OscilloSignalw /= 16;  		//20121002   8
		}
	else
		{
			OscilloSignalw /= 8;  		//20121002   8
		}
	if (OscilloSignalw > 255) OscilloSignalw = 255;

	if (OscilloSignal01b>PriOscilloSignal) DiffSignal = OscilloSignal01b - PriOscilloSignal;			//???????????????
	else	DiffSignal = 0;

	PriOscilloSignal = OscilloSignal01b;
	for(i=0;i<15;i++)
		{FilterRam[15-i] = FilterRam[14-i];}
	return;
}
//********************************************************************************
/*
void firfilter3(void)																			//Primitive subroutine
{
	unsigned char i;
	if(!RCSensorType) FilterRam[0] =  ZeroCountw - SensorCountw + 0x1000;
	else FilterRam[0] =  SensorCountw - ZeroCountw + 0x1000;
	if(UparmWWFlag)  OscilloSignalw =0x03C0;			//20121002 Uparm filter 3C0
	else    OscilloSignalw =0x6A0;								//20121002 WW filter

	OscilloSignalw += FilterRam[11];
	OscilloSignalw += FilterRam[12];
	OscilloSignalw -= FilterRam[0];
	OscilloSignalw -= FilterRam[23];
	OscilloSignalw += FilterRam[10];
	OscilloSignalw += FilterRam[13];
	OscilloSignalw *= 2;
	OscilloSignalw -= FilterRam[1];
	OscilloSignalw -= FilterRam[22];
	OscilloSignalw += FilterRam[9];
	OscilloSignalw += FilterRam[14];
	OscilloSignalw -= FilterRam[2];
	OscilloSignalw -= FilterRam[21];
	OscilloSignalw *= 2;
	OscilloSignalw -= FilterRam[0];
	OscilloSignalw -= FilterRam[23];
	OscilloSignalw += FilterRam[11];
	OscilloSignalw += FilterRam[12];
	OscilloSignalw -= FilterRam[1];
	OscilloSignalw -= FilterRam[22];
	OscilloSignalw -= FilterRam[2];
	OscilloSignalw -= FilterRam[21];
	OscilloSignalw += FilterRam[10];
	OscilloSignalw += FilterRam[13];
	OscilloSignalw -= FilterRam[20];
	OscilloSignalw -= FilterRam[3];
	OscilloSignalw += FilterRam[8];
	OscilloSignalw += FilterRam[15];
	OscilloSignalw -= FilterRam[19];
	OscilloSignalw -= FilterRam[4];
	OscilloSignalw += FilterRam[8];
	OscilloSignalw += FilterRam[15];
	OscilloSignalw -= FilterRam[19];
	OscilloSignalw -= FilterRam[4];

	if  (!UparmWWFlag)   					//20121002 WW filter
		{
				OscilloSignalw /= 50;
				if (OscilloSignalw > 0x7FFF) OscilloSignalw = 0;
		}
	else
		{
			OscilloSignalw /= 16;  		//20121002   16
			if  (OscilloSignalw > 0x7FFF )
				{
					OscilloSignalw = 0;
				}
		}
	if (OscilloSignalw > 255) OscilloSignalw = 255;
	if (OscilloSignal01b>PriOscilloSignal) DiffSignal = OscilloSignal01b - PriOscilloSignal;			//???????????????
	else	DiffSignal = 0;
	PriOscilloSignal = OscilloSignal01b;
	for(i=0;i<23;i++)
		{FilterRam[23-i] = FilterRam[22-i];}
	return;
}
*/
/*
void CalScale(void)
{
	UparmScaleValue=FuzzyMaxBackup;
	if(UparmWWFlag)
	{
		UparmScaleValue*=8;
		UparmScaleValue/=70;
		if(UparmScaleValue<7) UparmScaleValue=7;				//
		if(UparmScaleValue>32) UparmScaleValue=32;			//
		UparmBaseValue=UparmScaleValue*60;
	}
	else
	{
		if(FuzzyMaxBackup>200) 	UparmScaleValue*=8;
		else										UparmScaleValue*=10;
		UparmScaleValue/=70;

		if(UparmScaleValue>24) UparmScaleValue=24;
		if(UparmScaleValue<7) UparmScaleValue=7;

		UparmBaseValue=UparmScaleValue*60;
	}
}*/
//********************************************************************************
void firfilter2(void)
{
	unsigned char i;
	unsigned long int OscilloSignalw0;
	if(!RCSensorType) FilterRam[0] =  ZeroCountw - SensorCountw + 0x1000;
	else FilterRam[0] =  SensorCountw - ZeroCountw + 0x1000;
//	if(UparmWWFlag)  OscilloSignalw0 =0x01E0;				//20121002 Uparm filter
	OscilloSignalw0 =UparmBaseValue;		//20160630 Uparm filter

	OscilloSignalw0 += FilterRam[11];
	OscilloSignalw0 += FilterRam[12];
	OscilloSignalw0 -= FilterRam[0];
	OscilloSignalw0 -= FilterRam[23];
	OscilloSignalw0 += FilterRam[10];
	OscilloSignalw0 += FilterRam[13];
	OscilloSignalw0 *= 2;
	OscilloSignalw0 -= FilterRam[1];
	OscilloSignalw0 -= FilterRam[22];
	OscilloSignalw0 += FilterRam[9];
	OscilloSignalw0 += FilterRam[14];
	OscilloSignalw0 -= FilterRam[2];
	OscilloSignalw0 -= FilterRam[21];
	OscilloSignalw0 *= 2;
	OscilloSignalw0 -= FilterRam[0];
	OscilloSignalw0 -= FilterRam[23];
	OscilloSignalw0 += FilterRam[11];
	OscilloSignalw0 += FilterRam[12];
	OscilloSignalw0 -= FilterRam[1];
	OscilloSignalw0 -= FilterRam[22];
	OscilloSignalw0 -= FilterRam[2];
	OscilloSignalw0 -= FilterRam[21];


	OscilloSignalw0 += FilterRam[10];
	OscilloSignalw0 += FilterRam[13];
	OscilloSignalw0 -= FilterRam[20];
	OscilloSignalw0 -= FilterRam[3];
	OscilloSignalw0 += FilterRam[8];
	OscilloSignalw0 += FilterRam[15];
	OscilloSignalw0 -= FilterRam[19];
	OscilloSignalw0 -= FilterRam[4];
	OscilloSignalw0 += FilterRam[8];
	OscilloSignalw0 += FilterRam[15];
	OscilloSignalw0 -= FilterRam[19];
	OscilloSignalw0 -= FilterRam[4];


	OscilloSignalw0 /= UparmScaleValue;  		//20121002   8
	if  (OscilloSignalw0 > 0x7FFF ) {OscilloSignalw0 = 0;}

	if (OscilloSignalw0 > 255) OscilloSignalw0 = 255;
	OscilloSignalw=OscilloSignalw0;

	if (OscilloSignal01b>PriOscilloSignal) DiffSignal = OscilloSignal01b - PriOscilloSignal;			//???????????????
	else	DiffSignal = 0;

	PriOscilloSignal = OscilloSignal01b;
	for(i=0;i<23;i++)
		{FilterRam[23-i] = FilterRam[22-i];}
	return;

}
//********************************************************************************
/*
void algorithm1(void)
{
	if (T125ms == 0) OneShotDC = 0;
	else
		{
			if (OneShotDC == 0)
				{
					OneShotDC = 1;
					showpres();
				}
		}
	if ((Countw%40) == 0)
		{
			heartsignon();
			BUZZER_EN;
		}
	else
		{
			if ((Countw%40) > 8)
				{
					heartsignoff();
					BUZZER_DIS;
				}
		}
	if(PressuremmHgw<40)
		{
			MaxAmpValue=Countw%15;
			SysMeanEnd=AscVal[MaxAmpValue];
			SysMeanEnd<<=1;
			DiaMeanEnd=SysMeanEnd*7/10;
			PulseMeanEnd=DiaMeanEnd*5/6;
			SystolicValue1b=SysMeanEnd;
			SystolicValue1b+=SysTab[MaxAmpValue];
			DiastolicValue=DiaMeanEnd;
			DiastolicValue+=DiaTab[MaxAmpValue];
			PulseRate=PulseMeanEnd;
 			if (SystolicValuew > DiastolicValue)
				TemplateValuelw = SystolicValuew - (unsigned int)DiastolicValue;
			else
				TemplateValuelw = 0;
			if ((DiastolicValue < 20) || (SystolicValuew < 50)) TemplateValuelw = 0;
			if ((TemplateValuelw >= 11 && TemplateValuelw <= 153))
				{
					BB= VALVEOFF | PUMPOFF;
					iocontroloff();
					if(IsPowerOn)
 						{
							BUZZER_EN;
							delay(127);
							BUZZER_DIS;
						}
					ResultCode = 0;
				}
			else ResultCode = 5;
			IsAlgoEnd = TRUE;
			IsAlgorithm = FALSE;
			PressuremmHgw = 0x0000;
		}
	Countw++;
	if(HeartSign==0)
		{
			BUZZER_DIS;
			heartsignoff();
			HeartSign=1;
		}
	if ((IsShowPressure == ON)&&(HeartSign==1)) showpres();
	if (PeakFlag == ON)
		{
			if (IsShowPressure == ON) showpressure();
			if (AlgoFirstPFlag == ON)
				{
					HeartSign=1;
					heartsignon();
				}
			if (AlgoOnePFlag == ON) BUZZER_EN;
		}
	if (NormalResultCode==1)
		{
			NormalResultCode=0;
 			BB= VALVEOFF | PUMPOFF;
			iocontroloff();
 			BUZZER_EN;
			delay(127);
 			BUZZER_DIS;
		}
}
*/
/*======================================
  [ algorithm PROGRAM ]
  function: for algorithm function call
  I/P:
  O/P:
  ======================================*/

void algorithm(void)
{
	if (T125ms == 0) OneShotDC = 0;
	else
		{
			if (OneShotDC == 0)
				{
					OneShotDC = 1;
					showpres();
				}
		}
	if ((Countw%40) == 0)
		{
			heartsignon();
			BUZZER_EN;
  	   }
  	   else
		{
			if ((Countw%40) > 8)
				{
					heartsignoff();
					BUZZER_DIS;
				}
		}
   if(PressuremmHgw<40)
		{
			MaxAmpValue=Countw%15;
			SysMeanEnd=AscVal[MaxAmpValue];
			SysMeanEnd<<=1;
			DiaMeanEnd=SysMeanEnd*7/10;
			PulseMeanEnd=DiaMeanEnd*5/6;
			SystolicValue1b=SysMeanEnd;
			SystolicValue1b+=SysTab[MaxAmpValue];
			DiastolicValue=DiaMeanEnd;
			DiastolicValue+=DiaTab[MaxAmpValue];
			PulseRate=PulseMeanEnd;
 			if (SystolicValuew > DiastolicValue)
				TemplateValuelw = SystolicValuew - (unsigned int)DiastolicValue;
			else
				TemplateValuelw = 0;
			if ((DiastolicValue < 20) || (SystolicValuew < 50)) TemplateValuelw = 0;
			if ((TemplateValuelw >= 11 && TemplateValuelw <= 153))
			{
					BB= VALVEOFF | PUMPOFF;
					iocontroloff();
					if(IsPowerOn)
					{
              				BUZZER_EN;
              				delay(127);
              				BUZZER_DIS;
					}
					ResultCode = 0;
			}
			else ResultCode = 5;
			IsAlgoEnd = TRUE;
			IsAlgorithm = FALSE;
			PressuremmHgw = 0x0000;
		}
	Countw++;
	if(HeartSign==0)
		{
			BUZZER_DIS;
			heartsignoff();
			HeartSign=1;
		}
	if ((IsShowPressure == ON)&&(HeartSign==1)) showpres();
	if (PeakFlag == ON)
		{
			if (IsShowPressure == ON) showpressure();
			if (AlgoFirstPFlag == ON)
				{HeartSign=1;
				heartsignon();
				}
			if (AlgoOnePFlag == ON) BUZZER_EN;
		}
	if (NormalResultCode==1)
		{
			NormalResultCode=0;
 			BB= VALVEOFF | PUMPOFF;
  			iocontroloff();
 			BUZZER_EN;
			delay(127);
 			BUZZER_DIS;
		}
}
void	fuzzydetect(void){
	FuzzyF = 255 - OscilloSignal01b;
	if (PressuremmHgw < 49)
 		{
           FuzzyMaxTemp = 0;
           FuzzyMaxValue = 15;
        }
	else
        {
 			if (FuzzyF>15)
 				{
					FuzzyMaxTemp = FuzzyMaxValue-2;
						if (FuzzyF > FuzzyMaxTemp )
							{
								SetPressureVw = PressuremmHgw + 60;
								if ( FuzzyF > FuzzyMaxValue ) FuzzyMaxValue = FuzzyF;
								if (PressuremmHgw > 170) SetPressureVw -= 12;
								if (PressuremmHgw > 140) SetPressureVw += 6;
								if (PressuremmHgw < 124) SetPressureVw -= 8;
								if (PressuremmHgw < 84) SetPressureVw -= 8;
							}
					if  (FuzzyMaxValue > 185 && PressuremmHgw < 65 )
						{
							FuzzyMaxTemp = 0;
							FuzzyMaxValue = 65;
							SetPressureVw = 185;
						}
				}
		}
	if (PressuremmHgw > 200)
		{
			if (FuzzyMaxValue < 21)
				{
					BB= VALVEOFF | PUMPOFF ;
					iocontroloff();
					IsAlgoEnd = TRUE;
					ResultCode = 3;
				}
		}
	if (PressuremmHgw > 135 && PressuremmHgw < 150 )
		{
			if (FuzzyMaxValue < 65 && SetPressureVw < 162)
				SetPressureVw = 162;
			if (FuzzyMaxValue < 39 && SetPressureVw < 205)
 	          	SetPressureVw = 205;
		}
	if (SetPressureVw < 160) SetPressureVw = 160;
	if (SetPressureVw >= 280) SetPressureVw = 280;
	if (FuzzyMaxValue > 185 &&  SetPressureVw < 185)  SetPressureVw = 185;
    if (FuzzyMaxValue < 60 &&  SetPressureVw < 200)  SetPressureVw = 210;
    if(UparmWWFlag==0)
    	{if(SetPressureVw<180)SetPressureVw=180;}
}

/*======================================
  [ PAD PROGRAM ]
  function: PAD SUB
  I/P:PulseRateDIM
  O/P:PADflag
  ======================================*/
//**************************************************
void PADDetect(void)
{
	unsigned int TotalTime=0;
	unsigned char SetTime=0;
	unsigned char i;
	unsigned char UpPulse;
	unsigned char DownPulse;
	unsigned char MDPulse;

	UpPulse=0;
	DownPulse=0;
	MDPulse=0;
	PADFlag=0;
	for(i=0;i<=HRPulseCount;i++)
		{TotalTime+=PulseRateDIM[i];}
	TotalTime/=(HRPulseCount+1);		//间隔时间平均值
	SetTime=TotalTime/6;				//取平均值的1/6作为基准.

	for (i=0;i<HRPulseCount;i++)
		{
			if(PulseRateDIM[i]>PulseRateDIM[i+1]){TotalTime=(PulseRateDIM[i]-PulseRateDIM[i+1]);}
			else{TotalTime=(PulseRateDIM[i+1]-PulseRateDIM[i]);}
			if(TotalTime>=SetTime) UpPulse++;
		}

		if(PulseRate<100)
		{
			if(HRPulseCount<10)
			{
				if(UpPulse>2) {PADFlag=1;}
			}
			else if(HRPulseCount<20)
			{
				if(UpPulse>3) {PADFlag=1;}
			}
			else
			{
				if(UpPulse>4) {PADFlag=1;}
			}
		}
		else if(PulseRate<110)
		{
			if(UpPulse>7) {PADFlag=1;}
		}
}


void	algorithminit(void)
{

	PriPressureV=PressuremmHgw;
	MeanIndex=1;
	ThresholdValue = 6;
	MaxDiffSignal = 0;
	HighPeakValue = 0;
	LowPeakValue = 255;
	MaxSlopeValue = 0;
	AlgoStateFlag.b = 0;
	AlgorithmFlag.b = 0;
	MaxAmpValue = 0;
	DetermineValue = 0;
	NOMORE1 = 0;
	Countw = 0;
	MarkCount = 0;
	PriMarkCount = 0;
	IntervalCount = 32;
	PulseCount = 0;
	HRPulseCount=0;
	RefindPulseCount = 0;
	TruePulseCount = 0;
	PulseRate=80;
	SumInterval=0;
	PP=0;
	do
		{
			PulseRam[PP].w = 0;
			if(PP <= 4)  AmpValue[PP] = 255;
			if(PP<=2)  PulsePressure[PP].w = 0;
			PP++;
		}while(PP<=62);
	NOMORE3 = 0;
	DetermineValueDia=0x00;
	SystolicValuew=0x0000;
	DiastolicValue=0xff;
	MinInterval=0xff;
	MAPValue=0x00;
	HRPulseCountSUM=0;
	//LeakageValue[0] = 50;
	//LeakageValue[1] = 50;
	//LeakageSet=200;			//20110322 新增漏速控制
	RepumpCheckFlag=1;		//20111204 新增再充气的条件.
/*
	if(UparmWWFlag)
		{
			InflateValueSet=165;    //20120717
			DeflateValueSet=250;
		}
	else
		{
			InflateValueSet=165;    //20120717
			DeflateValueSet=250;
		}
*/
	FuzzyMaxValue=0;
	SetPressureOKFlag=0;
	for(PP=0;PP<24;PP++)
		{FilterRam[PP] = 0;}
	PP=0;

	MoveFlag=0;

}


void DPDetect(unsigned char SYS,unsigned char DIA)
{
	unsigned char diff;
	diff=SYS-DIA;
	if(KeyNumber==7&&!DPIconDisable)
	{
		if(diff<50){ DPIconOff;}
		if(diff>=80){ DPIconOn;}
		if((diff>=50)&&(diff<80)){DPIconOn;}
	}
	else
	{
		if(diff<50){ OutGreenOn;OutRedOff;/*OutGreen=1;OutRed=0;*/}
		if(diff>=80){ OutRedOn;OutGreenOff;/*OutRed=1;OutGreen=0;*/}
		if((diff>=50)&&(diff<80)){OutRedOn;OutGreenOn;/*OutGreen=1;OutRed=1;*/}
	}
}






void CalScale(void)
{

}
